package com.liuzy.tool;

import java.io.FileInputStream;
import java.io.InputStream;
import java.net.URL;
import java.security.KeyStore;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;

/**
 * 双向认证HTTPS工具
 *
 * @author liuzy
 * @since 2015年11月3日
 */
public class HTTPS extends HTTP {
	private KeyManager[] km;
	private TrustManager[] tm;
	public void cientCer(String p12FilePath, String p12Pwd) throws Exception {
		InputStream keyStoreInputStream = new FileInputStream(p12FilePath);
	    KeyStore keyStore = KeyStore.getInstance("PKCS12");
	    keyStore.load(keyStoreInputStream, p12Pwd.toCharArray());
	    KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
	    keyManagerFactory.init(keyStore, p12Pwd.toCharArray());
	    km = keyManagerFactory.getKeyManagers();
	}
	public void trustCer(String jksFilePath, String jksPwd) throws Exception {
		InputStream trustStoreInputStream = new FileInputStream(jksFilePath);
	    KeyStore trustStore = KeyStore.getInstance("JKS");
	    trustStore.load(trustStoreInputStream, jksPwd.toCharArray());
	    TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
	    trustManagerFactory.init(trustStore);
	    tm = trustManagerFactory.getTrustManagers();
	}

	private SSLSocketFactory createSSLSocketFactory() {
		try {
			if (km == null) {
				km = new KeyManager[0];
			}
			if (tm == null) {
				tm = new TrustManager[] { new X509TrustManager() {
					@Override
					public X509Certificate[] getAcceptedIssuers() {
						return null;
					}
					@Override
					public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
					}
					@Override
					public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
					}
				} };
			}
			SSLContext context = SSLContext.getInstance("TLS");
			context.init(km, tm, null);
			return context.getSocketFactory();
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
	protected String request(String url, String method) {
		url = setUrlParams(url);
		log(method, url);
		String result = "";
		HttpsURLConnection conn = null;
		int code = 0;
		try {
			URL uri = new URL(url);
			conn = (HttpsURLConnection) uri.openConnection();
			conn.setSSLSocketFactory(createSSLSocketFactory());
			conn.setRequestMethod(method);
			conn.setConnectTimeout(timeout);
			conn.setReadTimeout(timeout);
			conn.setUseCaches(false);
			setHeader(conn);
			writeBody(conn);
			conn.connect();
			code = conn.getResponseCode();
			InputStream inputStream = conn.getInputStream();
			result = readStream(inputStream);
		} catch (Exception e) {
			result = "{\"status\":" + code + ",\"message\":\"" + e.getMessage() + "\"}";
		} finally {
			conn.disconnect();
			clear();
		}
		log("RESUT", result);
		return result;
	}
}
